package com.huawang.mdesign.model.service.util;


import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Design的缓存数据
 */

@Slf4j
//@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DesignCache {

        /**
         * 保存缓存数据
         */
        private static final Map<String, Object> cache = new ConcurrentHashMap<>();

        /**
         * 保存缓存对应的过期时间
         */
        private static final Map<String, Long> cacheExpireRecord = new ConcurrentHashMap<>();

        //lombok 生成private构造函数  sonr不起作用
        private DesignCache() {
        }

    /**
     * 根据key获取对应的缓存
     * @param key
     * @return
     */
    public static Pair<Boolean, Optional<Object>> getFromCache(String key) {
            boolean cacheContainsKey = true;
            Object value = null;
            Long expireTime = cacheExpireRecord.get(key);
            // 如果存在这个Key
            if (expireTime != null) {
                // 如果数据已经过期，此处使用了延迟删除，只有查询发现过期了才会删除
                // 0L是特殊的，它代表永不过期
                if (expireTime != 0L && expireTime < System.currentTimeMillis()) {
                    log.info("DESIGN CACHE缓存过期：" + key);
                    deleteCache(key);
                    cacheContainsKey = false;
                } else {
                    // 从缓存中获取数据
                    value = cache.get(key);
                }
            } else {
                cacheContainsKey = false;
            }
            return Pair.of(cacheContainsKey, Optional.ofNullable(value));
        }


    /**
     * 删除某个前缀开头key对应的所有缓存
     * @param keyPrefix
     * @return
     */
    public static int deleteCache(String keyPrefix) {
            Set<String> keys = new HashSet<>();
            // 先查到以这个前缀开头的所有Key
            cache.forEach((k, v) -> {
                if (k.startsWith(keyPrefix)) {
                    keys.add(k);
                }
            });
            // 遍历这些Key，依次清除
            keys.forEach(key -> {
                cacheExpireRecord.remove(key);
                cache.remove(key);
                log.info("DESIGN CACHE缓存清除：" + key);
            });
            return keys.size();
        }

    /**
     * 删除所有缓存
     */
    public static void deleteCacheAll() {
        cache.clear();
    }


    /**
     * 设置Map缓存
     * @param key
     * @param value
     * @param timeToLive
//     * @param timeUnit
     */
        public static void setCache(String key, Object value, long timeToLive, Date date) {
            cache.put(key, value);
            // 记录失效时间，0L是特殊的，它代表永不过期
            if (timeToLive <= 0L) {
                cacheExpireRecord.put(key, 0L);
            } else {
                cacheExpireRecord.put(key, System.currentTimeMillis() + date.getTime());
            }
        }
    }




